/**
 * 
 */
package ro.dta.idbi.model;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;

import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;

import com.mxgraph.io.mxCodec;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxCellRenderer;
import com.mxgraph.util.png.mxPngEncodeParam;
import com.mxgraph.util.png.mxPngImageEncoder;

import ro.dta.idbi.interfaces.ISaveStrategy;

/**
 * PNG save strategy, used to save a graph as a PNG file
 * 
 * @author Tudor Dobrila
 * 
 */
public class SaveStrategyPng implements ISaveStrategy {

	@Override
	public String getExtension() {
		return ".png";
	}

	@Override
	public FileFilter getFileFilter() {
		return new ImageFilter();
	}

	@Override
	public void save(mxGraphComponent graphComponent, mxCodec codec, String path)
			throws IOException {
		exportPng(graphComponent, codec, path, Color.white);
	}

	/**
	 * Export diagram as an image (PNG) to the file filename
	 * 
	 * @param graphComponent
	 *            Graph component holding the graph to be exported
	 * @param codec
	 *            Codec used by the metamodel
	 * @param filename
	 *            Path to file where diagram is exported
	 * @param background
	 *            Background color of the diagram in the exported file
	 */
	public static void exportPng(final mxGraphComponent graphComponent, mxCodec codec,
			final String filename, final Color background) throws IOException {
		final BufferedImage image = mxCellRenderer
				.createBufferedImage(graphComponent.getGraph(), null, 1, background,
						graphComponent.isAntiAlias(), null, graphComponent.getCanvas());

		final String xml = URLEncoder.encode(SaveStrategyXml.exportXml(graphComponent, codec), "UTF-8");
		final mxPngEncodeParam param = mxPngEncodeParam.getDefaultEncodeParam(image);
		param.setCompressedText(new String[] { "mxGraphModel", xml });

		final FileOutputStream outputStream = new FileOutputStream(new File(filename));
		try {
			final mxPngImageEncoder encoder = new mxPngImageEncoder(outputStream, param);

			if (image == null) {
				JOptionPane.showMessageDialog(graphComponent, "Could not export graph to image",
						"Error", JOptionPane.ERROR_MESSAGE);
			} else {
				encoder.encode(image);
			}
		} finally {
			outputStream.close();
		}
	}

	/**
	 * Filter used to show only images in the JFileChooser
	 * 
	 * @author Tudor Dobrila
	 * 
	 */
	static class ImageFilter extends FileFilter {

		@Override
		public boolean accept(final File file) {
			boolean result = false;
			if (file.isDirectory()) {
				result = true;
			} else {
				final int dotPos = file.getName().lastIndexOf(".");
				if (dotPos != -1) {
					final String extension = file.getName().substring(dotPos).toLowerCase();

					if (".png".equals(extension)) {
						result = true;
					}
				}
			}

			return result;
		}

		@Override
		public String getDescription() {
			return "PNG files (.png)";
		}

	}

}
